home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Down Under Games
/
The Best of Down Under Games.iso
/
3dfx Screen Savers
/
VoodooLights
/
Sources
/
clip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-15
|
7KB
|
298 lines
/*------------------------------------------------------/
/ /
/ Copyright 1997, SΘrgio Durte <smd@di.fct.unl.pt> /
/ /
/------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <glide.h>
#include "defines.h"
#include "hw.h"
#include "mat.h"
#include "cam.h"
#include "clip.h"
#define clp_MAX_VERTEX 40
extern Bool wireFrame ;
static Vector Vm[ clp_MAX_VERTEX ] ;
static Vector *Vb[ clp_MAX_VERTEX ] ;
static int nM ;
static void clp_ClipZ_MinusW( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
{
int d, j, n = 0 ;
for( j = 0 ; j < nVi ; j++ ){
Vector *vp = Vi[j] ;
Vector *vq = Vi[j+1] ;
XYZW *p = (XYZW *)vp ;
XYZW *q = (XYZW *)vq ;
if( p->z < -p->w ) { /* falha */
if( q->z > -q->w ) { /* passa */
Float lambda = -(p->z + p->w) / (q->z - p->z + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
} else {
Vo[n++] = vp ; /* passa */
if( q->z < -q->w ) { /* falha */
Float lambda = -(p->z + p->w) / (q->z - p->z + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d] ) ;
Vo[n++] = M ; }
}
}
Vo[n] = Vo[0] ; /* sentinela */
*nVo = n ;
}
static void clp_ClipZ_ZER0( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
{
int j, d, n = 0 ;
for( j = 0 ; j < nVi ; j++ ){
Vector *vp = Vi[j] ;
Vector *vq = Vi[j+1] ;
XYZW *p = (XYZW *)vp ;
XYZW *q = (XYZW *)vq ;
if( p->z > 0.0f ) { /* falha */
if( q->z < 0.0f ) { /* passa */
Float lambda = -p->z / (q->z - p->z ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
} else {
Vo[n++] = vp ;
if( q->z > 0.0f ) { /* falha */
Float lambda = -p->z / (q->z - p->z ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
}
}
Vo[n] = Vo[0] ; /* sentinela */
*nVo = n ;
}
static void clp_ClipX_MinusW( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
{
int j, d, n = 0 ;
for( j = 0 ; j < nVi ; j++ ){
Vector *vp = Vi[j] ;
Vector *vq = Vi[j+1] ;
XYZW *p = (XYZW *)vp ;
XYZW *q = (XYZW *)vq ;
if( p->x < -p->w ) { /* falha */
if( q->x > -q->w ) { /* passa */
Vector *M = & Vm[ nM++ ] ;
Float lambda = -(p->x + p->w) / (q->x - p->x + q->w - p->w ) ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
} else {
Vo[n++] = vp ; /* passa */
if( q->x < -q->w ) { /* falha */
Vector *M = & Vm[ nM++ ] ;
Float lambda = -(p->x + p->w) / (q->x - p->x + q->w - p->w ) ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
}
}
Vo[n] = Vo[0] ; /* sentinela */
*nVo = n ;
}
static void clp_ClipY_MinusW( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
{
int j, d, n = 0 ;
for( j = 0 ; j < nVi ; j++ ){
Vector *vp = Vi[j] ;
Vector *vq = Vi[j+1] ;
XYZW *p = (XYZW *)vp ;
XYZW *q = (XYZW *)vq ;
if( p->y < -p->w ) { /* falha */
if( q->y > -q->w ) { /* passa */
Float lambda = -(p->y + p->w) / (q->y - p->y + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
} else {
Vo[n++] = vp ; /* passa */
if( q->y < -q->w ) { /* falha */
Float lambda = -(p->y + p->w) / (q->y - p->y + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
}
}
Vo[n] = Vo[0] ; /* sentinela */
*nVo = n ;
}
static void clp_ClipX_W( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
{
int j, d, n = 0 ;
for( j = 0 ; j < nVi ; j++ ){
Vector *vp = Vi[j] ;
Vector *vq = Vi[j+1] ;
XYZW *p = (XYZW *)vp ;
XYZW *q = (XYZW *)vq ;
if( p->x > p->w ) { /* falha */
if( q->x < q->w ) { /* passa */
Float lambda = (p->x - p->w) / (-(q->x - p->x) + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
} else {
Vo[n++] = vp ; /* passa */
if( q->x > q->w ) { /* falha */
Float lambda = (p->x - p->w) / (-(q->x - p->x) + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
}
}
Vo[n] = Vo[0] ; /* sentinela */
*nVo = n ;
}
static void clp_ClipY_W( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Vo[] )
{
int j, d, n = 0 ;
for( j = 0 ; j < nVi ; j++ ){
Vector *vp = Vi[j] ;
Vector *vq = Vi[j+1] ;
XYZW *p = (XYZW *)vp ;
XYZW *q = (XYZW *)vq ;
if( p->y > p->w ) { /* falha */
if( q->y < q->w ) { /* passa */
Float lambda = (p->y - p->w) / (-(q->y - p->y) + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
} else {
Vo[n++] = vp ; /* passa */
if( q->y > q->w ) { /* falha */
Float lambda = (p->y - p->w) / (-(q->y - p->y) + q->w - p->w ) ;
Vector *M = & Vm[ nM++ ] ;
for( d = 0 ; d < dims ; d++ )
(*M)[d] = (*vp)[d] + lambda * ( (*vq)[d] - (*vp)[d]) ;
Vo[n++] = M ;
}
}
}
Vo[n] = Vo[0] ; /* sentinela */
*nVo = n ;
}
static void clp_DrawPolygon( int n, XYZWRGBAST *v[])
{
int i, ilist[ clp_MAX_VERTEX ] ;
GrVertex vtx[ clp_MAX_VERTEX ] ;
if( n < 3 ) return ;
for( i = 0 ; i < n ; i++ ) {
ilist[i] = i ;
cam_XYZWRGBAST2Vertex( v[i], & vtx[i] ) ;
}
ilist[n] = ilist[0] ; /* sentinela */
grDrawPolygon(n, ilist, vtx ) ;
}
Bool clp_PointVisible( XYZW *p )
{
if( p->w < 0.0 || p->x < -p->w || p->x > p->w || p->y < -p->w || p->y > p->w || p->z < -p->w || p->z > 0.0 ) return False ;
else return True ;
}
void clp_ClipPolygonRef( int dims, int nVi, Vector *Vi[], int *nVo, Vector *Va[] )
{
int n ;
nM = 0 ;
Vi[nVi ] = Vi[0] ; /* sentinela */
clp_ClipX_MinusW( dims, nVi, Vi, & n, Vb ) ;
clp_ClipX_W( dims, n, Vb, & n, Va ) ;
clp_ClipY_MinusW( dims, n, Va, & n, Vb ) ;
clp_ClipY_W( dims, n, Vb, & n, Va ) ;
clp_ClipZ_MinusW( dims, n, Va, & n, Vb ) ;
clp_ClipZ_ZER0( dims, n, Vb, & n, Va) ;
clp_DrawPolygon( n, (XYZWRGBAST **)Va ) ;
*nVo = n ;
}